﻿#ifndef SERVIDOR_APLICACAO_H
#define SERVIDOR_APLICACAO_H

#include "ThreadConsole.h"
#include "ThreadSessao.h"
#include "Logger.h"
#include "../model/ServidorClientes.h"
#include "../model/ServidorArquivos.h"
#include "../model/Arquivo.h"
#include "../model/ModoAbertura.h"

#include <QDebug>
#include <QDir>
#include <QString>
#include <QList>
#include <QThread>
#include <QTextStream>
#include <QTcpServer>
#include <QHostAddress>
#include <QPair>

namespace controller {

	class ServidorAplicacao : public QTcpServer
	{
		Q_OBJECT
		private:

			QList<ThreadSessao*> threads;
			ThreadConsole *console;
			model::ServidorClientes *servidorClientes;
			model::ServidorArquivos *servidorArquivos;
			QHostAddress address;
			unsigned short porta;
			QString arquivosPath, clientesPath;

		protected:

			virtual void incomingConnection( int );

		public:

			explicit ServidorAplicacao( const QString &ip, const unsigned short &porta, QObject *parent = 0 );
			virtual ~ServidorAplicacao();

			virtual bool fileExistsEvent( const QString& );
			virtual model::Arquivo* adicionarArquivoEvent( const QString&, const QByteArray& );
			virtual void apagarArquivoEvent( model::Arquivo* );
			virtual model::Arquivo* getArquivoEvent( const QString &nome, model::ModoAbertura& );
			virtual QList<model::Arquivo*>* getArquivoPorExtEvent( const QString &, const model::ModoAbertura& );
			virtual QList<QPair<QString, model::ModoAbertura> >* listarDiretorioEvent();
			virtual void renomearArquivoEvent( model::Arquivo*, const QString & );

			virtual model::Cliente* getClienteEvent( const QString & );
			virtual model::Cliente* cadastrarClienteEvent( const QString & );
			virtual void logoutClienteEvent( model::Cliente* );

			int getThreadsAtivas() const { return threads.size(); }
			// ThreadLogger + ThreadConsole + Thread do SocketServer
			// + ThreadMain + as ThreadSessao ativas...
			int getTodasThreadsAtivas() const { return threads.size() + 4; }
			void listaArquivosAbertosClientes();

			void iniciar();

		signals:

			void terminateApp();

		public slots:

			void terminate();
			void removerThread( ThreadSessao* );
	};

}

#endif
